package com.company.cloud.user.modules.mgr.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.company.cloud.user.modules.api.response.RoleModel;
import com.company.cloud.user.modules.cache.utils.UserConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant.YNEnum;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.user.constant.ErrorUserEnum;
import com.company.cloud.user.modules.base.entity.RoleInfo;
import com.company.cloud.user.modules.base.entity.RolePermissionInfo;
import com.company.cloud.user.modules.base.entity.UserRoleInfo;
import com.company.cloud.user.modules.base.service.RoleInfoService;
import com.company.cloud.user.modules.base.service.RolePermissionInfoService;
import com.company.cloud.user.modules.base.service.UserRoleInfoService;
import com.company.cloud.user.modules.mgr.controller.req.RoleSaveParam;
import com.company.cloud.user.modules.mgr.controller.req.RoleUpdateParam;
import com.company.cloud.user.modules.mgr.service.RoleMgrService;

@Service
public class RoleMgrServiceImpl implements RoleMgrService {

	@Autowired
	private RolePermissionInfoService rolePermissionInfoService;
	@Autowired
	private UserRoleInfoService userRoleInfoService;
	@Autowired
	private RoleInfoService roleInfoService;

	@Transactional
	@Override
	public RoleModel save(RoleSaveParam params, LoginSimpleUserInfo userInfo) {
		ValidatorUtils.validate(params);
		// 角色
		RoleInfo roleInfo = new RoleInfo();
		roleInfo.setCompanyNo(params.getCompanyNo());
		roleInfo.setCode(params.getCode());
		roleInfo.setName(params.getName());
		roleInfo.setRemark(params.getRemark());
		roleInfo.setIsSys(params.getIsSys());
		roleInfo.addCreateParam(userInfo);
		roleInfo.addEditParam(userInfo);
		roleInfoService.save(roleInfo);
		// 角色和权限
		if (!CollectionUtils.isEmpty(params.getPermissionCodes())) {
			Set<RolePermissionInfo> rolePerSet = new HashSet<RolePermissionInfo>();
			for (String perCode : params.getPermissionCodes()) {
				if (!StringUtils.isEmpty(perCode)) {
					RolePermissionInfo rolePer = new RolePermissionInfo();
					rolePer.setCompanyNo(roleInfo.getCompanyNo());
					rolePer.setRoleCode(roleInfo.getCode());
					rolePer.setPerCode(perCode);
					rolePer.addCreateParam(userInfo);
					rolePer.addEditParam(userInfo);
					rolePerSet.add(rolePer);
				}
			}
			if (rolePerSet.size() > 0) {
				rolePermissionInfoService.saveBatch(rolePerSet);
			}
		}
		return UserConvertUtils.getRoleModel(roleInfo);
	}

	@Transactional
	@Override
	public RoleModel update(RoleUpdateParam params, LoginSimpleUserInfo userInfo) {
		ValidatorUtils.validate(params);
		// 角色
		RoleInfo roleInfo = roleInfoService.getById(params.getCode());
		if (null == roleInfo) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
//		if (YNEnum.YES.getCode().equals(roleInfo.getIsSys())) {
//			throw new BusinessException(ErrorUserEnum.Role_Has_Sys);
//		}
		roleInfo.setName(params.getName());
		roleInfo.setRemark(params.getRemark());
		roleInfo.addEditParam(userInfo);
		roleInfoService.updateById(roleInfo);

		// 角色和权限
		rolePermissionInfoService.remove(new QueryWrapper<RolePermissionInfo>()
				.eq("role_code", roleInfo.getCode()));

		// 角色和权限
		if (!CollectionUtils.isEmpty(params.getPermissionCodes())) {
			Set<RolePermissionInfo> rolePerSet = new HashSet<RolePermissionInfo>();
			for (String perCode : params.getPermissionCodes()) {
				if (!StringUtils.isEmpty(perCode)) {
					RolePermissionInfo rolePer = new RolePermissionInfo();
					rolePer.setCompanyNo(roleInfo.getCompanyNo());
					rolePer.setRoleCode(roleInfo.getCode());
					rolePer.setPerCode(perCode);
					rolePer.addCreateParam(userInfo);
					rolePer.addEditParam(userInfo);
					rolePerSet.add(rolePer);
				}
			}
			if (rolePerSet.size() > 0) {
				rolePermissionInfoService.saveBatch(rolePerSet);
			}
		}

//		// 角色关联的用户退出
//		List<UserRoleInfo> userRoleList = userRoleInfoService.list(new QueryWrapper<UserRoleInfo>()
//				.eq("role_code", roleInfo.getCode()).eq("company_no", roleInfo.getCompanyNo()));
	 	return UserConvertUtils.getRoleModel(roleInfo);
	}

	@Override
	public RoleModel get(String code) {
		RoleInfo roleInfo = roleInfoService.getById(code);
		if (null == roleInfo ) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
		List<RolePermissionInfo> rolePerList = rolePermissionInfoService.list(
				new QueryWrapper<RolePermissionInfo>()
						.eq("role_code", roleInfo.getCode())
		);
		RoleModel  data= UserConvertUtils.getRoleModel(roleInfo,rolePerList);
		return data;
	}

	@Transactional
	@Override
	public List<UserRoleInfo> delete(String code, LoginSimpleUserInfo userInfo) {
		if(StringUtils.isEmpty(code)) {
			throw new BusinessException(BaseReturnEnum.CompanyNo_NULL);
		}
		RoleInfo roleInfo = roleInfoService.getById(code);
		if (null == roleInfo ) {
			throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
		}
//		if(YNEnum.YES.getCode().equals(roleInfo.getIsSys()) ) {
//			throw new BusinessException("系统角色");
//		}
		//删除角色
		roleInfoService.removeById(code);
		
		//角色关联的用户退出
		List<UserRoleInfo> userRoleList= userRoleInfoService.list(new QueryWrapper<UserRoleInfo>()
				.eq("role_code", roleInfo.getCode())
				.eq("company_no", roleInfo.getCompanyNo())
				);
		
		//删除角色权限
		rolePermissionInfoService.remove(new QueryWrapper<RolePermissionInfo>()
				.eq("company_no", roleInfo.getCompanyNo())
				.eq("role_code", roleInfo.getCode())
			);
		
		//删除角色用户
		userRoleInfoService.remove(new QueryWrapper<UserRoleInfo>()
					.eq("role_code", roleInfo.getCode())
					.eq("company_no", roleInfo.getCompanyNo())
				);
		
		return userRoleList;
	}

}
